package com.jifeng.api.crud.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.jifeng.api.crud.dao.VwOrderUserDao;
import com.jifeng.api.crud.entity.FeeConfigEntity;
import com.jifeng.api.crud.entity.VwOrderUserEntity;
import com.jifeng.api.crud.service.FeeConfigService;
import com.jifeng.api.crud.service.VwOrderUserService;
import com.jifeng.api.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;


@Service("vwOrderUserService")
@Slf4j
public class VwOrderUserServiceImpl extends ServiceImpl<VwOrderUserDao, VwOrderUserEntity> implements VwOrderUserService {

    @Autowired
    FeeConfigService feeConfigService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        try {
            String status = "";
            QueryWrapper<VwOrderUserEntity> queryWrapper = new QueryWrapper<>();

            if (params.get("name") != null && !StringUtils.isEmpty(params.get("name").toString())) {
                String name = params.get("name").toString();
                queryWrapper.eq("name", name);
            }

            if (params.get("mobile") != null && !StringUtils.isEmpty(params.get("mobile").toString())) {
                String mobile = params.get("mobile").toString();
                queryWrapper.eq("mobile", mobile);
            }

            if (params.get("status") != null && !StringUtils.isEmpty(params.get("status").toString())) {
                status = params.get("status").toString();
                switch (status) {
                    case "0":
                        queryWrapper.eq("status", 4);
                        break;
                    case "1":
                        queryWrapper.eq("status", 4);
                        break;
                    case "2":
                        queryWrapper.eq("status", 7);
                        break;
                    case "3":
                        queryWrapper.eq("status", 6);
                        break;
                }
            } else {
                queryWrapper.and(Wrapper -> {
                    Wrapper.eq("status", 4).or()
                            .eq("status", 7).or()
                            .eq("status", 6);
                });
            }

            IPage<VwOrderUserEntity> page = this.page(
                    new Query<VwOrderUserEntity>().getPage(params),
                    queryWrapper
            );

            FeeConfigEntity feeConfigEntity = feeConfigService.getById(1);

            List<VwOrderUserEntity> orderUserEntities = page.getRecords().stream().map(item -> {
                // 设置订单状态 0 正常，1 超时，2 完成，3欠费
                if (item.getStatus() == 7) {
                    item.setState("2");
                } else if (item.getStatus() == 6) {
                    item.setState("3");
                } else if (item.getStatus() == 4) {
                    if (DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) < feeConfigEntity.getBaseHour()) {
                        item.setState("0");
                    } else if (DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) >= feeConfigEntity.getBaseHour()) {
                        item.setState("1");
                    }
                }

                // 设置已租赁时间
                if (item.getEndFeeTime() == null) {
                    int minuteSum = new Long(DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.MINUTE)).intValue();
                    int hour = minuteSum / 60;
                    int minute = minuteSum - (hour * 60);
                    item.setRentTime(hour + "小时" + minute + "分钟");
                } else {
                    int minuteSum = new Long(DateUtil.between(item.getStartFeeTime(), item.getEndFeeTime(), DateUnit.MINUTE)).intValue();
                    int hour = minuteSum / 60;
                    int minute = minuteSum - (hour * 60);
                    item.setRentTime(hour + "小时" + minute + "分钟");
                }
                return item;
            }).collect(Collectors.toList());


            if (status.equals("0")) {
                List<VwOrderUserEntity> entities = orderUserEntities.stream().filter(item -> DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) < feeConfigEntity.getBaseHour()).collect(Collectors.toList());
                page.setRecords(entities);
            } else if (status.equals("1")) {
                List<VwOrderUserEntity> entities = orderUserEntities.stream().filter(item -> DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) >= feeConfigEntity.getBaseHour()).collect(Collectors.toList());
                page.setRecords(entities);
            }

            return new PageUtils(page);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("path：{}，errMsg：{}", getRequestUrl(), e.getMessage());
            return null;
        }
    }

    @Override
    public R exportCash(HttpServletResponse response, Map<String, Object> params) {
        try {
            String name =Convert.toStr(params.get("name"));
            String start_time = Convert.toStr(params.get("start_time"));
            String end_time = Convert.toStr(params.get("end_time"));

            // 租赁金额总值
            AtomicInteger totalFee = new AtomicInteger();
            // 已付金额总值
            AtomicInteger totalPaidFee = new AtomicInteger();
            // 欠额总值
            AtomicInteger totalNeedFee = new AtomicInteger();

            /**
             * 获取费用配置信息
             */
            FeeConfigEntity feeConfigEntity = feeConfigService.getById(1);

            /**
             * 根据用户名查询数据
             */
            List<VwOrderUserEntity> orderUserEntities = this.list(new QueryWrapper<VwOrderUserEntity>().eq("name", name));
            List<List<String>> collect = orderUserEntities.stream().filter(item -> item.getStartFeeTime() != null).filter(orderUser -> {
                DateTime parseStartTime = DateUtil.parse(start_time);
                DateTime parseEndTime = DateUtil.parse(end_time);
                int compareStart = DateUtil.compare(orderUser.getStartFeeTime(), parseStartTime);
                int compareEnd = DateUtil.compare(parseEndTime, orderUser.getStartFeeTime());
                return compareStart >= 0 && compareEnd >= 0;
            }).map(item -> {
                List<String> list = new ArrayList<>();
                /**
                 * 计算已租赁时间
                 */
                int minuteSum = 60;
                if (item.getEndFeeTime() == null) {
                    minuteSum = new Long(DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.MINUTE)).intValue();
                } else {
                    minuteSum = new Long(DateUtil.between(item.getStartFeeTime(), item.getEndFeeTime(), DateUnit.MINUTE)).intValue();
                }
                int hour = minuteSum / 60;
                int minute = minuteSum - (hour * 60);
                item.setRentTime(hour + "小时" + minute + "分钟");

                /**
                 * 格式化开始租赁时间
                 */
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String startTime = format.format(item.getStartFeeTime());

                /**
                 * 设置订单状态 0 正常，1 超时，2 完成，3欠费
                 */
                if (item.getStatus() == 7) {
                    item.setState("完成");
                } else if (item.getStatus() == 6) {
                    item.setState("欠费");
                } else if (item.getStatus() == 4) {
                    if (DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) < feeConfigEntity.getBaseHour()) {
                        item.setState("正常");
                    } else if (DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) >= feeConfigEntity.getBaseHour()) {
                        int extraCost = RegexUtils.orderIsOvertime(item.getStartFeeTime(), new Date(), feeConfigEntity.getBaseHour(), feeConfigEntity.getExtFee());
                        item.setFee(extraCost + item.getFee());
                        item.setAmount(new Long(item.getFee()) - item.getPaidFee());
                        item.setState("超时");
                    }
                }

                /**
                 * 添加数据
                 */
                list.add(startTime);
                list.add(item.getRentTime());
                list.add(item.getMobile());
                list.add(item.getState());
                list.add(String.valueOf(item.getFee() / 100));
                list.add(String.valueOf(item.getPaidFee() / 100));
                list.add(String.valueOf(item.getAmount() / 100));

                totalFee.addAndGet(item.getFee());
                totalPaidFee.addAndGet(item.getPaidFee());
                totalNeedFee.addAndGet(item.getAmount().intValue());
                return list;
            }).collect(Collectors.toList());

            List<List<String>> excelData = new ArrayList<>();

            List<String> fees = new ArrayList<>();
            fees.add(String.valueOf(totalFee.intValue() / 100));
            fees.add(String.valueOf(totalPaidFee.intValue() / 100));
            fees.add(String.valueOf(totalNeedFee.intValue() / 100));

            List<String> header = new ArrayList<>();
            header.add("户主名称：" + name);
            header.add("起止日期：" + start_time + " 至 " + end_time);

            List<String> head = new ArrayList<>();
            head.add("起租时间");
            head.add("租赁时间");
            head.add("客户手机号");
            head.add("租赁状态");
            head.add("租赁金额");
            head.add("已交金额");
            head.add("欠额");

            excelData.add(head);
            excelData.addAll(collect);
            excelData.add(fees);

            String sheetName = "现金明细表";
            String fileName = "现金明细表_" + name + ".xls";

            ExcelUtil.exportExcel(response, excelData, header, sheetName, fileName, 15, 0);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("path：{}，errMsg：{}", getRequestUrl(), e.getMessage());
            return R.sysError();
        }
    }

    @Override
    public R exportCashSummary(HttpServletResponse response, Map<String, Object> params) {
        try {
            String start_time = Convert.toStr(params.get("start_time"));
            String end_time = Convert.toStr(params.get("end_time"));

            // 租赁金额总值
            AtomicInteger totalFee = new AtomicInteger();
            // 已付金额总值
            AtomicInteger totalPaidFee = new AtomicInteger();
            // 欠额总值
            AtomicInteger totalNeedFee = new AtomicInteger();
            /**
             * 获取费用配置信息
             */
            FeeConfigEntity feeConfigEntity = feeConfigService.getById(1);

            /**
             * 根据用户名查询数据
             */
            List<VwOrderUserEntity> orderUserEntities = this.list();
            List<List<String>> collect = orderUserEntities.stream().filter(item -> item.getStartFeeTime() != null).filter(orderUser -> {
                DateTime parseStartTime = DateUtil.parse(start_time);
                DateTime parseEndTime = DateUtil.parse(end_time);
                int compareStart = DateUtil.compare(orderUser.getStartFeeTime(), parseStartTime);
                int compareEnd = DateUtil.compare(parseEndTime, orderUser.getStartFeeTime());
                return compareStart >= 0 && compareEnd >= 0;
            }).map(item -> {
                List<String> list = new ArrayList<>();

                if (item.getStatus() == 4) {
                    if (DateUtil.between(item.getStartFeeTime(), new Date(), DateUnit.HOUR) >= feeConfigEntity.getBaseHour()) {
                        int extraCost = RegexUtils.orderIsOvertime(item.getStartFeeTime(), new Date(), feeConfigEntity.getBaseHour(), feeConfigEntity.getExtFee());
                        item.setFee(extraCost + item.getFee());
                        item.setAmount(new Long(item.getFee()) - item.getPaidFee());
                    }
                }
                /**
                 * 添加数据
                 */
                list.add(String.valueOf(item.getFee() / 100));
                list.add(String.valueOf(item.getPaidFee() / 100));
                list.add(String.valueOf(item.getAmount() / 100));
                list.add(item.getName());

                totalFee.addAndGet(item.getFee());
                totalPaidFee.addAndGet(item.getPaidFee());
                totalNeedFee.addAndGet(item.getAmount().intValue());
                return list;
            }).collect(Collectors.toList());

            List<List<String>> excelData = new ArrayList<>();

            List<String> fees = new ArrayList<>();
            fees.add(String.valueOf(totalFee.intValue() / 100));
            fees.add(String.valueOf(totalPaidFee.intValue() / 100));
            fees.add(String.valueOf(totalNeedFee.intValue() / 100));

            List<String> header = new ArrayList<>();
            header.add("起止日期：" + start_time + " 至 " + end_time);

            List<String> head = new ArrayList<>();
            head.add("租赁金额");
            head.add("已交金额");
            head.add("欠额");
            head.add("户主名称");

            excelData.add(head);
            excelData.addAll(collect);
            excelData.add(fees);

            String sheetName = "现金统计表";
            String fileName = "现金统计表.xls";

            ExcelUtil.exportExcel(response, excelData, header, sheetName, fileName, 15, 1);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("path：{}，errMsg：{}", getRequestUrl(), e.getMessage());
            return R.sysError();
        }
    }

    public String getRequestUrl() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getRequestURI();
    }
}